#include <func.h>
#include "Command.h"
#include "Crypto.h"

extern UserInfo info;

int do_login(int connfd)
{
    static time_t last = (time_t)0;
    time_t now = time(NULL);
    if (now - last < 60) {
        printf("尝试次数过多，请稍后再试\n");
        return -1;
    }

    int counts = 0;         // 尝试次数
    while (counts < 3) {
        char username[26] = "";
        char passwd[26] = "";

        printf("用户名: ");
        scanf("%s", username);

        // 禁用回显
        struct termios old_termios;
        disable_echo(STDIN_FILENO, &old_termios);

        printf("密码: ");
        scanf("%s", passwd);
        printf("\n");

        while(getchar() != '\n')
            ;

        // 恢复回显
        restore_echo(STDIN_FILENO, &old_termios);

        // 1. 构建 Request
        Request req;
        bzero(&req, sizeof(req));
        req.type = REQ_LOGIN;
        // 用户名 密码
        sprintf(req.value, "%s %s", username, passwd);
        printf("DEBUG: %s\n", req.value);

        // 设置 req.length
        req.length = strlen(req.value);

        // 2. 发送 Request
        int length = 2 * sizeof(int) + req.length;
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &req, length, MSG_WAITALL);

        // 3. 接收 Response
        Response resp;
        bzero(&resp, sizeof(resp));
        recv(connfd, &length, sizeof(int), MSG_WAITALL);
        recv(connfd, &resp, length, MSG_WAITALL);

        switch (resp.status) {
        case RESP_OK:
            info.islogin = true;
            strcpy(info.username, username);
            path_init(&info.cwd);
            strcpy(info.token, resp.value);
            printf("恭喜您，登录成功!\n");
            printf("DEBUG: jwt = %s\n", info.token);
            return 0;
        case RESP_ERROR:
            printf("用户名或密码错误!\n");
            counts++;
            break;
        }
    }
    
    last = time(NULL);
    printf("您已失败了3次，请稍后再试!\n");
    return -1;
}

int do_register(int connfd)
{
    for (;;) {
        char username[26] = "";
        char passwd[26] = "";
        char confirm[26] = "";

        printf("用户名: ");
        scanf("%s", username);

        // 禁用回显
        struct termios old_termios;
        disable_echo(STDIN_FILENO, &old_termios);

        printf("密码: ");
        scanf("%s", passwd);
        printf("\n");
        printf("确认密码: ");
        scanf("%s", confirm);
        printf("\n");

        // 恢复回显
        restore_echo(STDIN_FILENO, &old_termios);

        if (strcmp(passwd, confirm) != 0) {
            printf("密码不一致, 请重新输入!\n");
            continue;
        }
        // 1. 密码一致, 构建 Request
        Request req;
        bzero(&req, sizeof(req));
        req.type = REQ_REGISTER;
        // 用户名 密码
        sprintf(req.value, "%s %s", username, passwd);
        printf("DEBUG: %s\n", req.value);

        // 设置 req.length
        req.length = strlen(req.value);

        // 2. 发送 Request
        int length = 2 * sizeof(int) + req.length;
        send(connfd, &length, sizeof(int), MSG_WAITALL);
        send(connfd, &req, length, MSG_WAITALL);

        // 3. 接收 Response
        Response resp;
        bzero(&resp, sizeof(resp));
        recv(connfd, &length, sizeof(int), MSG_WAITALL);
        recv(connfd, &resp, length, MSG_WAITALL);

        switch (resp.status) {
        case RESP_OK:
            printf("恭喜您，注册成功!\n");
            return 0;   // 注册成功
        case RESP_EXIST:
            printf("用户名已存在!\n");
            continue;
        // other cases...
        }
    }
    return -1;  // 注册失败
}

void login_or_register(int connfd)
{
    printf("请选择 (L)登录, (R)注册, (E)退出: ");
    fflush(stdout);

    char c;
    scanf(" %c", &c);
    while (getchar() != '\n')   // 跳过这一行剩余的字符
        ;

    switch(c) {
    case 'L': case 'l':
        do_login(connfd);
        break;
    case 'R': case 'r':
        do_register(connfd);
        break;
    case 'E': case 'e':
        exit(0);
        break;
    default:
        printf("输入有误，请重新输入\n");
        break;
    }
}
